import fs from 'fs'
import path from 'path'
import { Command, flags } from '@oclif/command'
import cli from 'cli-ux'
import { ffmpegHelper } from './ffmpegHelper'
import { BatchRepairer } from './BatchRepairer'

class VideoRepair extends Command {

  static description = '视频文件修复工具'

  static flags = {
    version: flags.version({ char: 'v' }),
    help: flags.help({ char: 'h' }),
    src: flags.string({ char: 's', required: true, description: '待处理的路径' })
  }

  async run() {
    const { args, flags } = this.parse(VideoRepair)
    console.log('args', args)
    console.log('flags', flags)
    const ext = this.getSrcExt(flags.src)
    if (ext === '.mp4') {
      this.repairSingleVideo(flags.src)
    } else if (ext === '.json') {
      this.continueRepair(flags.src)
    } else {
      this.repairVideoByDirectory(flags.src)
    }
  }

  private getSrcExt(src: string) {
    if (!fs.existsSync(src)) {
      throw new Error(`${src} not found`)
    }
    const ext = path.extname(src).toLocaleLowerCase()
    if (ext === '' || ext === '.json' || ext === '.mp4') {
      return ext
    }
    throw new Error(`Unsupported file type: ${ext}`)
  }

  private repairSingleVideo(videoSrc: string) {
    console.time('耗时')
    const bar = cli.progress({
      format: 'repair [{bar}] {percentage}% | 预计剩余时间: {eta}s',
    })
    const newSrcPath = path.join(path.dirname(videoSrc), `${path.basename(videoSrc, path.extname(videoSrc))}_old${path.extname(videoSrc)}`)
    fs.renameSync(videoSrc, newSrcPath)
    bar.start(100, 0)
    ffmpegHelper.simpleRepair(newSrcPath, videoSrc, (percent) => {
      bar.update(Math.floor(percent))
    }).then(() => {
      console.info('修复完成')
    }).finally(() => {
      bar.stop()
      console.timeEnd('耗时')
    })
  }

  private async repairVideoByDirectory(dirSrc: string) {
    let obj = new BatchRepairer()
    obj.dirPath = dirSrc
    let now = new Date()
    const filename = `${now.getFullYear()}-${(now.getMonth() + 1)}-${now.getDate()} ${now.getHours()}-${now.getMinutes()}.json`
    obj.saveJsonPath = path.join(path.resolve('./'), filename)
    obj.start()
  }

  private async continueRepair(jsonPath: string) {
    let data = JSON.parse(fs.readFileSync(jsonPath, { encoding: 'utf-8' }))
    let obj = new BatchRepairer()
    obj.curentIndex = data.curentIndex
    obj.dirPath = data.dirPath
    obj.saveJsonPath = data.saveJsonPath
    obj.step = data.step
    obj.tasks = data.tasks
    obj.time = data.time
    obj.start()
  }

}

export = VideoRepair
